﻿using UnityEngine;
using LiftIndicatorMOD;
using System;
using spaar.ModLoader;
using System.Collections.Generic;

public class LiftIndicatorModScript : MonoBehaviour
{

    /// <summary>
    /// 模拟模式下升力组件列表
    /// </summary>
    public static List<LiftBlockScript> liftBlocks = new List<LiftBlockScript>();

    public static List<LiftIndicatorModScript> liftIndicators = new List<LiftIndicatorModScript>();

    /// <summary>
    /// 总升力
    /// </summary>
    public Vector3 liftResultant = Vector3.zero;

    public static Vector3 spoint = Vector3.zero;

    /// <summary>
    /// 总升力指示器
    /// </summary>
    public LineRenderer liftIndicator = new LineRenderer();

    public bool Visiable = true;

    public bool Calculate = true;

    bool firstFrame = true;

    // Use this for initialization
    void Start()
    {
        liftIndicators.Add(this);

        //放置模块引发事件
        Game.OnBlockPlaced += AddLiftBlockScript;

        //加载存档引发事件
        XmlLoader.OnLoad += AddLiftBlockScript;

        liftIndicator = gameObject.AddComponent<LineRenderer>();
        liftIndicator.SetVertexCount(2);
        liftIndicator.useWorldSpace = true;
        liftIndicator.SetWidth(0.5f, 0.5f);
        liftIndicator.SetColors(Color.blue, Color.green);
        liftIndicator.material = new Material(Shader.Find("Particles/Additive"));
        ;
    }

    // Update is called once per frame
    void Update()
    {

        liftIndicator.enabled = Visiable && SettingWindow.liftIndicatorVisiabled;

        if (StatMaster.isSimulating)
        {
            if (firstFrame)
            {
                firstFrame = false;
                AddLiftBlock_to_liftList();
            }

            if (Calculate)
            {
                liftResultant = calculate();
            }

            if (liftIndicator.enabled)
            {              
                liftIndicator.SetPosition(0, spoint);
                liftIndicator.SetPosition(1, liftResultant);
            }
        }
        else
        {
            firstFrame = true;

            if (Calculate)
            {
                liftResultant = calculate_build();
            }

            if (liftIndicator.enabled)
            {                
                liftIndicator.SetPosition(0, spoint);
                liftIndicator.SetPosition(1, liftResultant);
            }
        }


    }

    static Vector3 calculate()
    {
        Vector3 result = Vector3.zero;
        Vector3 point = Vector3.zero;
        float scale = 0f;

        foreach (var block in liftBlocks)
        {
            if (block.Calculate)
            {
                result += block.liftVector;
             }
        }

        foreach (var block in liftBlocks)
        {
            if (block.Calculate)
            {
                scale = block.liftVector.magnitude / result.magnitude;
                point += scale * block.transform.position;
            }
        }
        spoint = point;
        return result;

    }

    static Vector3 calculate_build()
    {
        List<LiftBlockScript> liftBlocks = LiftBlockScript.liftBlocks;

        Vector3 result = Vector3.zero;
        Vector3 point = Vector3.zero;
        float scale = 0f;
        
        foreach (var block in liftBlocks)
        {
            if (block.Calculate)
            {
                result += block.liftVector;
            }
        }

        foreach (var block in liftBlocks)
        {
            if (block.Calculate)
            {
                scale = block.liftVector.magnitude / result.magnitude;
                point += scale * block.transform.position; 
            }
        }

        spoint = point;
        return result;

    }

    public static void AddLiftBlockScript(MachineInfo info)
    {
        try
        {
            liftBlocks.Clear();
            LiftBlockScript.liftBlocks.Clear();
            liftIndicators.Clear();
            foreach (var block in Machine.Active().BuildingBlocks)
            {
                AddLiftBlockScript(block.transform);
            }
        }
        catch (Exception e)
        {
            Debug.Log("load " + e.Message);
        }
    }

    public static void SetAllEnable(bool value)
    {
        foreach (var indicator in liftIndicators)
        {
            indicator.liftIndicator.enabled = value;
            indicator.enabled = value;
        }
    }

    /// <summary>
    /// 为升力模块添加升力计算脚本
    /// </summary>
    /// <param name="block"></param>
    static void AddLiftBlockScript(Transform block)
    {
        if (LiftBlockScript.isLiftBlock(block.GetComponent<BlockBehaviour>().GetBlockID()))
        {
            
            if (block.GetComponent<LiftBlockScript>() == null)
            {
                block.gameObject.AddComponent<LiftBlockScript>();
            }
            else
            {
                LiftBlockScript.liftBlocks.Add(block.GetComponent<LiftBlockScript>());
            }
        }
    }
    /// <summary>
    /// 模拟模式下添加升力模块到升力模块列表中
    /// </summary>
    static void AddLiftBlock_to_liftList()
    {
        liftBlocks.Clear();
        foreach (var block in Machine.Active().IntactBlocks)
        {
            if (LiftBlockScript.isLiftBlock(block.GetBlockID()))
            {
                liftBlocks.Add(block.GetComponent<LiftBlockScript>());
            }
        }
    }

    

  


   
}
